package com.edu.exam.entity.examination.online;

import com.edu.exam.enums.SessionConfigType;
import com.edu.exam.enums.SessionValueType;
import com.edu.exam.enums.SessionConfigStatus;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

/**
 * 会话配置实体类
 * 所属模块：E-01 考试执行模块
 * 对应数据库表：session_configuration
 *
 * <p>考试会话配置实体，用于管理上机考试会话的各项配置参数。
 * 支持考试参数、功能开关、安全设置、显示配置等多种配置类型的管理。</p>
 *
 * @author System
 * @version 1.0.0
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@EntityListeners(AuditingEntityListener.class)
public class SessionConfiguration {

    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 会话ID
     *
     * <p>关联的考试会话ID，标识配置所属的会话。
     * 与ExamSession实体建立一对一关系。</p>
     */
    @Column(name = "session_id", nullable = false, length = 32, unique = true)
    private String sessionId;

    /**
     * 配置类型
     *
     * <p>配置的类型标识。
     * 支持的类型：EXAM_PARAMS（考试参数）、FEATURE_SWITCHES（功能开关）、
     * SECURITY_SETTINGS（安全设置）、DISPLAY_CONFIG（显示配置）等。</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "config_type", nullable = false, length = 30)
    private SessionConfigType configType;

    /**
     * 配置键
     *
     * <p>配置项的键名，用于标识具体的配置项。
     * 支持层级结构的配置键，如"exam.duration"、"security.auth.method"等。</p>
     */
    @Column(name = "config_key", nullable = false, length = 100)
    private String configKey;

    /**
     * 配置值
     *
     * <p>配置项的值，支持字符串、数字、布尔、JSON等格式。
     * 根据配置类型和键名确定值的具体格式和含义。</p>
     */
    @Column(name = "config_value", columnDefinition = "TEXT")
    private String configValue;

    /**
     * 配置数据类型
     *
     * <p>配置值的数据类型。
     * 支持的类型：STRING（字符串）、INTEGER（整数）、BOOLEAN（布尔值）、
     * JSON（JSON对象）、ARRAY（数组）等。</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "value_type", nullable = false, length = 20)
    private SessionValueType valueType = SessionValueType.STRING;

    /**
     * 默认值
     *
     * <p>配置项的默认值。
     * 当配置值为空时使用的默认值。</p>
     */
    @Column(name = "default_value", columnDefinition = "TEXT")
    private String defaultValue;

    /**
     * 配置描述
     *
     * <p>配置项的详细描述信息。
     * 用于说明配置项的作用、使用方法和注意事项。</p>
     */
    @Column(name = "config_description", length = 500)
    private String configDescription;

    /**
     * 是否激活
     *
     * <p>标识配置项是否激活。
     * true表示激活，false表示禁用。</p>
     */
    @Column(name = "is_active", nullable = false)
    private Boolean isActive = true;

    /**
     * 是否必需
     *
     * <p>标识配置项是否必需。
     * true表示必需，false表示可选。</p>
     */
    @Column(name = "is_required", nullable = false)
    private Boolean isRequired = false;

    /**
     * 是否可运行时修改
     *
     * <p>标识配置项是否可以在会话运行时动态修改。
     * true表示可以运行时修改，false表示只能在会话开始前修改。</p>
     */
    @Column(name = "is_runtime_editable", nullable = false)
    private Boolean isRuntimeEditable = false;

    /**
     * 验证规则
     *
     * <p>JSON格式的验证规则配置。
     * 用于验证配置值的有效性，如数值范围、字符串长度、正则表达式等。</p>
     */
    @Column(name = "validation_rules", columnDefinition = "TEXT")
    private String validationRules;

    /**
     * 依赖配置
     *
     * <p>依赖的其他配置项键名列表。
     * 当前配置项可能依赖于其他配置项的值。</p>
     */
    @Column(name = "dependencies", length = 500)
    private String dependencies;

    /**
     * 配置版本
     *
     * <p>配置项的版本号。
     * 用于配置变更的版本管理和兼容性控制。</p>
     */
    @Column(name = "config_version")
    private Integer configVersion = 1;

    /**
     * 配置优先级
     *
     * <p>配置项的优先级，数值越大优先级越高。
     * 用于配置冲突时的优先级判断。</p>
     */
    @Column(name = "priority")
    private Integer priority = 0;

    /**
     * 配置标签
     *
     * <p>配置项的标签列表，JSON格式。
     * 用于配置的分类、搜索和过滤。</p>
     */
    @Column(name = "config_tags", columnDefinition = "TEXT")
    private String configTags;

    /**
     * 配置组
     *
     * <p>配置项所属的配置组。
     * 用于相关配置项的分组管理。</p>
     */
    @Column(name = "config_group", length = 50)
    private String configGroup;

    /**
     * 最后修改者ID
     *
     * <p>最后修改配置的用户ID。
     * 用于记录配置变更的操作人。</p>
     */
    @Column(name = "last_modified_by", length = 32)
    private String lastModifiedBy;

    /**
     * 最后修改者姓名
     *
     * <p>最后修改配置的用户姓名。
     * 冗余存储用户姓名，避免频繁关联查询用户表。</p>
     */
    @Column(name = "last_modified_by_name", length = 100)
    private String lastModifiedByName;

    /**
     * 生效时间
     *
     * <p>配置的生效时间。
     * 配置在指定时间之后才开始生效。</p>
     */
    @Column(name = "effective_time")
    private LocalDateTime effectiveTime;

    /**
     * 失效时间
     *
     * <p>配置的失效时间。
     * 配置在指定时间之后自动失效。</p>
     */
    @Column(name = "expiry_time")
    private LocalDateTime expiryTime;

    /**
     * 配置状态
     *
     * <p>配置项的状态。
     * 支持的状态：DRAFT（草稿）、ACTIVE（激活）、SUSPENDED（暂停）、DEPRECATED（废弃）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "config_status", nullable = false, length = 20)
    private SessionConfigStatus configStatus = SessionConfigStatus.ACTIVE;

    // ===== 审计字段 =====

    /**
     * 创建时间
     */
    @CreatedDate
    @Column(name = "created_time", nullable = false, updatable = false)
    private LocalDateTime createdTime;

    /**
     * 更新时间
     */
    @LastModifiedDate
    @Column(name = "updated_time", nullable = false)
    private LocalDateTime updatedTime;

  }